import { i18n } from '@app-nextmesh/common/utils';
import {
  ErrorTips,
  FormField,
  FormFieldSet,
  FormNativeSelect,
} from '@app-nextmesh/components/Forms/components';
import { InputValueType } from '@app-nextmesh/types';
import { useEffect, useRef, useState } from 'react';
import { ISelectOption, SelectOptionValueType } from '../types';
import JSONFormatForm from './JSONFormatForm';
import { getLabel, makeDefaultForm } from './components/utils';

interface IProps {
  readonly: boolean;
  formFormat: object; // { { Type:{ "Hard": {}, "Linear": {...} } ...} 包含多个键值的JSON对象
  form?: { Type: string; Value: object }; // {"Type": "Hard", "Value": {}}
  onInputChange: (value: any) => void;
  indicesAssigned: Set<string>; // 保存已被使用的entity index
  switchedOnEntityGroup: string; //
  handleSwitchEntityGroup: (name: string) => void;
}

export default function ObjectType({
  readonly,
  formFormat,
  form: initForm,
  onInputChange,
  indicesAssigned,
  switchedOnEntityGroup,
  handleSwitchEntityGroup,
}: IProps) {
  const [form, setForm] = useState(initForm);
  const formRef = useRef<any>();

  useEffect(() => {
    setForm(initForm);
    formRef.current = initForm;
  }, [initForm]);

  if (!initForm) {
    return <></>;
  }

  // 获取type对象的键列表，用于下拉选择框
  const typeKeys = Object.keys(formFormat['Type']);
  // 切换类型
  const handleSelectChange = (value: SelectOptionValueType) => {
    const type = value as string;
    // 根据formFormat生成form.Value默认值
    const formData = makeDefaultForm(formFormat['Type'][type]);
    const newForm = { Type: type, Value: formData };
    formRef.current = newForm;
    setForm(newForm);
    onInputChange(newForm);
  };
  const handleInputChange = (name: string, value: InputValueType) => {
    formRef.current.Value[name] = value;
    onInputChange(formRef.current);
  };
  // 判断form.Type是否在typeKeys中
  if (!typeKeys.includes(form.Type)) {
    return <ErrorTips>{`格式错误，无效的Default：${form.Type}`}</ErrorTips>;
  }
  const options = typeKeys.map((value) => {
    let label = formFormat['Type'][value].Label;
    if (!label || label.length === 0) {
      label = value;
    }
    label = getLabel(label);
    return { label, value } as ISelectOption;
  });

  return (
    <>
      <FormField label={i18n.t('option')}>
        <FormNativeSelect
          disabled={readonly}
          options={options}
          value={form.Type}
          onChange={handleSelectChange}
        />
      </FormField>
      <FormFieldSet>
        <JSONFormatForm
          readonly={readonly}
          formData={form.Value}
          formFormat={formFormat['Type'][form.Type]}
          handleInputChange={handleInputChange}
          indicesAssigned={indicesAssigned}
          switchedOnEntityGroup={switchedOnEntityGroup}
          handleSwitchEntityGroup={handleSwitchEntityGroup}
        />
      </FormFieldSet>
    </>
  );
}
